package com.beyondsoft.mcms.domain;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooJpaActiveRecord(finders = { "findConferencesByNameLikeAndConferenceTypeAndConferenceStatus",
		"findConferencesByConferenceStatus", "findConferencesByNameEquals" })
public class Conference {

	/**
     */
	@ManyToOne
	private Item conferenceType;

	/**
     */
	@NotNull
	@ManyToOne
	private Item conferenceStatus;

	/**
     */
	@NotNull
	@Column(unique = true)
	private String name;

	/**
     */
	@NotNull
	private String topic;

	/**
     */
	@NotNull
	private String sponsor;

	/**
     */
	@NotNull
	private String organizer;

	/**
     */
	private String coOrganizer;

	/**
     */
	@NotNull
	private String place;

	/**
     */
	@NotNull
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = "M-")
	private Date holdDate;

	/**
     */
	private Integer holdDays;

	/**
     */
	@NotNull
	@Pattern(regexp = "^([0-1]?[0-9]|[2][0-3]):([0-5][0-9])-([0-1]?[0-9]|[2][0-3]):([0-5][0-9])$")
	private String holdTime;

	/**
     */
	@NotNull
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = "M-")
	private Date registrationStartTime;

	/**
     */
	@NotNull
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = "M-")
	private Date registrationEndTime;

	/**
     */
	private int maxEntries = 1000;

	/**
     */
	@Size(max = 500)
	private String description;

	/**
     */
	@NotNull
	private String createdBy;

	/**
     */
	private String updatedBy;

	/**
     */
	@NotNull
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = "MM")
	private Date createDate;

	/**
     */
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = "MM")
	private Date updateDate;

	public static TypedQuery<Conference> findConferencesByNameLikeAndConferenceTypeAndConferenceStatus(String name,
			Item conferenceType, Item conferenceStatus) {
		if (name == null || name.length() == 0) name = "*";
		name = name.replace('*', '%');
		if (name.charAt(0) != '%') {
			name = "%" + name;
		}
		if (name.charAt(name.length() - 1) != '%') {
			name = name + "%";
		}
		EntityManager em = Conference.entityManager();
		if (conferenceType == null && conferenceStatus == null) {
			TypedQuery<Conference> q = em
					.createQuery(
							"SELECT o FROM Conference AS o WHERE LOWER(o.name) LIKE LOWER(:name) ORDER BY o.registrationEndTime desc ",
							Conference.class);
			q.setParameter("name", name);
			return q;
		} else if (conferenceType != null && conferenceStatus == null) {
			TypedQuery<Conference> q = em
					.createQuery(
							"SELECT o FROM Conference AS o WHERE LOWER(o.name) LIKE LOWER(:name)  AND o.conferenceType = :conferenceType ORDER BY o.registrationEndTime desc ",
							Conference.class);
			q.setParameter("name", name);
			q.setParameter("conferenceType", conferenceType);
			return q;
		} else if (conferenceType == null && conferenceStatus != null) {
			TypedQuery<Conference> q = em
					.createQuery(
							"SELECT o FROM Conference AS o WHERE LOWER(o.name) LIKE LOWER(:name)  AND o.conferenceStatus = :conferenceStatus ORDER BY o.registrationEndTime desc ",
							Conference.class);
			q.setParameter("name", name);
			q.setParameter("conferenceStatus", conferenceStatus);
			return q;
		} else {
			TypedQuery<Conference> q = em
					.createQuery(
							"SELECT o FROM Conference AS o WHERE LOWER(o.name) LIKE LOWER(:name)  "
									+ "AND o.conferenceStatus = :conferenceStatus AND o.conferenceType = :conferenceType ORDER BY o.registrationEndTime desc ",
							Conference.class);
			q.setParameter("name", name);
			q.setParameter("conferenceStatus", conferenceStatus);
			q.setParameter("conferenceType", conferenceType);
			return q;
		}
	}

}
